from datetime import datetime
from typing import Optional, Dict, Any
from backend.infrastructure.database import db
from backend.models.student import Student
from backend.models.student_extension import StudentExtension
from backend.constants import (
    upgrade_grade, calculate_age_for_year, estimate_grade_by_age,
    EXTENSION_FIELD_INHERITANCE
)

class StudentExtensionService:
    """学生扩展表自动管理服务"""
    
    def ensure_yearly_extension(self, student_id: int, target_year: str, 
                               data_source: str = "manual") -> StudentExtension:
        """确保指定年份的扩展记录存在"""
        try:
            # 检查是否已存在该年份的记录
            existing = StudentExtension.query.filter_by(
                student_id=student_id,
                data_year=target_year
            ).first()
            
            if existing:
                return existing
            
            # 不存在则创建新记录
            return self._create_yearly_extension(student_id, target_year, data_source)
            
        except Exception as e:
            print(f"确保年份扩展记录失败: {e}")
            return None
    
    def _create_yearly_extension(self, student_id: int, target_year: str, 
                                data_source: str) -> StudentExtension:
        """创建新年份的扩展记录"""
        try:
            # 获取最新的扩展记录作为继承基础
            latest_extension = self._get_latest_extension(student_id)
            
            # 创建新记录
            new_extension = StudentExtension(
                student_id=student_id,
                data_year=target_year
            )
            
            # 自动计算字段
            new_extension.age = calculate_age_for_year(student_id, target_year)
            new_extension.grade = self._calculate_target_year_grade(
                student_id, latest_extension, target_year
            )
            
            # 继承字段
            if latest_extension:
                self._inherit_fields_from_latest(new_extension, latest_extension)
            
            # 保存到数据库
            db.session.add(new_extension)
            db.session.commit()
            
            print(f"自动创建{target_year}年扩展记录 - 学生{student_id}")
            return new_extension
            
        except Exception as e:
            db.session.rollback()
            print(f"创建年份扩展记录失败: {e}")
            return None
    
    def _get_latest_extension(self, student_id: int) -> Optional[StudentExtension]:
        """获取学生最新年份的扩展记录"""
        return StudentExtension.query.filter_by(
            student_id=student_id
        ).order_by(StudentExtension.data_year.desc()).first()
    
    def _calculate_target_year_grade(self, student_id: int, 
                                    latest_extension: Optional[StudentExtension], 
                                    target_year: str) -> Optional[str]:
        """计算目标年份的年级"""
        try:
            if not latest_extension:
                # 没有历史记录，根据年龄推算
                age = calculate_age_for_year(student_id, target_year)
                return estimate_grade_by_age(age) if age else None
            
            # 有历史记录，根据年份差值升级
            year_diff = int(target_year) - int(latest_extension.data_year)
            
            if year_diff <= 0:
                # 目标年份不晚于最新记录，保持原年级
                return latest_extension.grade
            
            # 逐年升级
            current_grade = latest_extension.grade
            for _ in range(year_diff):
                current_grade = upgrade_grade(current_grade)
            
            return current_grade
            
        except Exception as e:
            print(f"计算目标年份年级失败: {e}")
            return None
    
    def _inherit_fields_from_latest(self, new_extension: StudentExtension, 
                                   latest_extension: StudentExtension):
        """从最新记录继承字段"""
        try:
            # 继承相对固定的信息
            for field in EXTENSION_FIELD_INHERITANCE["relatively_fixed"]:
                if hasattr(latest_extension, field):
                    latest_value = getattr(latest_extension, field)
                    setattr(new_extension, field, latest_value)
            
            # 继承可变健康信息（如果没有新数据的话）
            for field in EXTENSION_FIELD_INHERITANCE["health_variable"]:
                if hasattr(latest_extension, field):
                    latest_value = getattr(latest_extension, field)
                    setattr(new_extension, field, latest_value)
            
        except Exception as e:
            print(f"继承字段失败: {e}")
    
    def batch_ensure_extensions_for_import(self, import_data: list, 
                                          import_year: str) -> Dict[int, StudentExtension]:
        """批量导入时确保扩展记录存在"""
        try:
            result = {}
            
            for student_id in set(item['student_id'] for item in import_data):
                extension = self.ensure_yearly_extension(
                    student_id, import_year, "import"
                )
                if extension:
                    result[student_id] = extension
            
            return result
            
        except Exception as e:
            print(f"批量确保扩展记录失败: {e}")
            return {}
    
    def validate_yearly_data_consistency(self, student_id: int) -> Dict[str, Any]:
        """验证学生多年数据的一致性"""
        try:
            extensions = StudentExtension.query.filter_by(
                student_id=student_id
            ).order_by(StudentExtension.data_year.asc()).all()
            
            issues = []
            
            for i in range(1, len(extensions)):
                prev_ext = extensions[i-1]
                curr_ext = extensions[i]
                
                # 检查年龄增长是否合理
                year_diff = int(curr_ext.data_year) - int(prev_ext.data_year)
                age_diff = (curr_ext.age or 0) - (prev_ext.age or 0)
                
                if abs(age_diff - year_diff) > 1:  # 允许1年的误差
                    issues.append({
                        "type": "age_inconsistency",
                        "year": curr_ext.data_year,
                        "message": f"年龄增长异常: {year_diff}年增长了{age_diff}岁"
                    })
                
                # 检查年级升级是否合理
                if prev_ext.grade and curr_ext.grade:
                    expected_grade = prev_ext.grade
                    for _ in range(year_diff):
                        expected_grade = upgrade_grade(expected_grade)
                    
                    if curr_ext.grade != expected_grade:
                        issues.append({
                            "type": "grade_inconsistency", 
                            "year": curr_ext.data_year,
                            "message": f"年级升级异常: 应为{expected_grade}, 实际为{curr_ext.grade}"
                        })
            
            return {
                "student_id": student_id,
                "total_years": len(extensions),
                "issues": issues,
                "is_consistent": len(issues) == 0
            }
            
        except Exception as e:
            print(f"验证数据一致性失败: {e}")
            return {"error": str(e)}

# 全局服务实例
student_extension_service = StudentExtensionService()

# 公共接口函数
def ensure_yearly_extension(student_id: int, target_year: str) -> StudentExtension:
    """公共接口：确保年份扩展记录存在"""
    return student_extension_service.ensure_yearly_extension(student_id, target_year)

def validate_student_yearly_data(student_id: int) -> Dict[str, Any]:
    """公共接口：验证学生多年数据一致性"""
    return student_extension_service.validate_yearly_data_consistency(student_id)
